/*
 *	create by senllang 2023/5/320
 *  mail : study@senllang.onaliyun.com
 *	for rwlock implements.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include "ipc_rwlock.h"


/*
 * 创建读写锁
 *
 * create by senllang 2023/5/20
 *
 * pMemAddr, 共享内存地址
 * Num， 读写锁数量，地址为连续存放
 */
int Initrwlock(char *pMemAddr, int Num)
{
	pthread_rwlock_t *pRwlock = NULL;
	pthread_rwlockattr_t rwlockAttr;
    int i = 0;
    	
	if((NULL == pMemAddr) || (Num == 0))
	{
		printf("Invalid args \n");
		return -1;
	}
	
	if(0 != pthread_rwlockattr_init(&rwlockAttr))
	{
	    printf("rwlock attr init err [%s]\n",strerror(errno));
        return -1;
    }
	
	if(0 != pthread_rwlockattr_setpshared(&rwlockAttr, PTHREAD_PROCESS_SHARED))
	{
        printf("rwlock attr setshare err[%s]\n",strerror(errno));
        return -1;
    }
	
	pRwlock = (pthread_rwlock_t*)pMemAddr;
	for(i = 0; i < Num; i++)
	{
		if(0 != pthread_rwlock_init(&pRwlock[i], &rwlockAttr))
		{
			printf("rwlock init err[%s]\n",strerror(errno));
			return -1;
		}	
	}
	
	pthread_rwlockattr_destroy(&rwlockAttr);
	
	return 0;
}

/*
 * 读写锁加读锁
 *
 * create by senllang 2023/5/20
 *
 * pMemAddr, 共享内存地址
 */
void Rdlock(char *pMemAddr)
{
	pthread_rwlock_t *pRwlock = (pthread_rwlock_t*)pMemAddr;
	pthread_rwlock_rdlock(pRwlock);
}

/*
 * 读写锁加写锁
 *
 * create by senllang 2023/5/20
 *
 * pMemAddr, 共享内存地址
 */
void Wrlock(char *pMemAddr)
{
	pthread_rwlock_t *pRwlock = (pthread_rwlock_t*)pMemAddr;
	pthread_rwlock_wrlock(pRwlock);
}

/*
 * 解锁读写锁
 *
 * create by senllang 2023/5/20
 *
 * pMemAddr, 共享内存地址
 */
void RwlockUnlock(char *pMemAddr)
{
	pthread_rwlock_t *pRwlock = (pthread_rwlock_t*)pMemAddr;
	pthread_rwlock_unlock(pRwlock);
}

/*
 * 销毁读写锁
 *
 * create by senllang 2023/5/20
 *
 * pMemAddr, 共享内存地址
 * Num， 读写锁数量，地址为连续存放
 */
void DestroyRwlock(char *pMemAddr, int Num)
{
	pthread_rwlock_t *pRwlock = (pthread_rwlock_t*)pMemAddr;
	
	for(int i = 0; i < Num; i++)
		pthread_rwlock_destroy(&pRwlock[i]);
}

/*
 * 获取读写锁内存大小
 *
 * create by senllang 2023/5/20
 *
 * Num， 读写锁数量，地址为连续存放
 */
int GetRwlockSize(int Num)
{
	return sizeof(pthread_rwlock_t)*Num;
}
